#!/usr/bin/python
# -*- coding: utf-8 -*-
import gtk
import gobject
import os
import platform
import urllib
import gettext
import platform
import sys
import gio
import threading
from Downloader import Downloader
from Message import Message
from Updater import Updater
_ = gettext.gettext
class DownloadView(gtk.VBox):
    def __init__(self):
        super(DownloadView, self).__init__()
        super(DownloadView, self).show()
        self.addButton = gtk.Button()
        self.delButton = gtk.Button()
        self.startButton = gtk.Button()
        self.cancelButton = gtk.Button()
        self.openButton = gtk.Button()
        self.downloaderMap = {}
        self.singleSelected = False
        self.model = None
        self.handlerId = []
        self.eventList = []
        self.email = ''
        self.path = ''
        self.filenameEntry = gtk.Entry()
        self.filenameEntry.set_editable(False)
        self.filenameEntry.set_tooltip_text(_('file path'))
        self.addDownloadIndex = 0
        self.nowConnected = None
        self.nowDeleting = []
        scrolledWindow = self.createList()
        #gtk.VPaned.add1(self, scrolledWindow)
        super(DownloadView, self).pack_start(scrolledWindow, expand=True, fill=True, padding=0)
        viewWindow = self.createText()
        super(DownloadView, self).pack_start(viewWindow, expand=False, fill=True, padding=0)
        super(DownloadView, self).show_all()
        #gtk.VPaned.add2(self, viewWindow)
        #gtk.VPaned.set_position(self, 330)
        self.updater = Updater(self.model, 
                               self.eventList, 
                               self.add, 
                               self.delete, 
                               self.__cancel,
                               self.__start, 
                               self.__resetId)
        
    def setConfig(self, configList):
        self.updater.stopUpdater()
        self.email = configList[0]
        self.path = configList[1]
        self.__disconnectButtons()
        while self.eventList:
            self.eventList.pop()
        self.updater.setEmail(self.email)
        if self.model:
            self.model.foreach(self.__iterativeRemove)
        self.updater.start()
            
    def __iterativeRemove(self, model, path, iterable):
        identity = model.get_value(iterable, 0)
        self.downloaderMap[identity].delete()
        self.downloaderMap.pop(identity)
        model.remove(iterable)
            
    def __disconnectButtons(self):
        print>>sys.stderr, "disconnect"
        if len(self.handlerId) == 4:
            identity = self.handlerId.pop()
            self.cancelButton.disconnect(identity)
            identity = self.handlerId.pop()
            self.startButton.disconnect(identity)
            identity = self.handlerId.pop()
            self.delButton.disconnect(identity)
            identity = self.handlerId.pop()
            self.openButton.disconnect(identity)
            self.filenameEntry.set_text('')
            
    def __connectButtons(self, model, iterable):
        print>>sys.stderr, "connect"
        if not self.handlerId:
            self.nowConnected = model.get_value(iterable, 0)
            self.handlerId.append(self.openButton.connect("clicked", self.__open, model, iterable))
            self.handlerId.append(self.delButton.connect("clicked", self.__delete, model, iterable))
            self.handlerId.append(self.startButton.connect("clicked", self.__start, model, iterable))
            self.handlerId.append(self.cancelButton.connect("clicked", self.__cancel, model, iterable))
            #self.handlerId = [
            #    self.openButton.connect("clicked", self.__open, model, iter),
            #    self.delButton.connect("clicked", self.__delete, model, iter),
            #    self.startButton.connect("clicked", self.__start, model, iter),
            #    self.cancelButton.connect("clicked", self.__cancel, model, iter)]
            self.filenameEntry.set_text(self.downloaderMap[model.get_value(iterable, 0)].getPath())
            self.filenameEntry.set_position(self.filenameEntry.get_text_length())
    
    def __listHandler(self, selection, model, path, isSelected, data):
        if not isSelected:
            iterable = model.get_iter(path)
            identity = model.get_value(iterable, 0)
            for i in self.nowDeleting:
                if identity == i:
                    self.singleSelected = False
                    return True
            if self.singleSelected:
                self.singleSelected = False
            else:                
                self.__connectButtons(model, iterable)
                self.singleSelected = True
            return True
        self.__disconnectButtons()
        return True
        
    def __resetId(self, iterable, idAfter):
        idBefore = self.model.get_value(iterable, 0)
        self.downloaderMap[idAfter] = self.downloaderMap[idBefore]
        del self.downloaderMap[idBefore]
        self.model.set_value(iterable, 0, idAfter)
        
    def add(self, identity, url, status='download', progress='0%'):
        if self.email and self.path:
            iterable = self.model.append([identity, url, '? bytes', '0 bytes', status, progress])
            self.downloaderMap[identity] = Downloader(url, self.path, self.model, iterable)
            
            if status == 'fail' or status == 'done':
                self.model.set_value(iterable, 4, status)
            else:
                if status == 'cancel':
                    self.downloaderMap[identity].cancel()
                elif status == 'delete': # this must not happend
                    self.delete(identity, iterable)
                else:
                    self.downloaderMap[identity].start()
                    
    def __add(self, widget):
        if self.email and self.path:
            from TextEntryDialog import TextEntryDialog
            textEntryDialog = TextEntryDialog()
            url = textEntryDialog.run()
            textEntryDialog.destroy()
            if url:
                identity = self.updater.addDownload(url)
                if identity != -1:
                    self.add(identity, url)
        else:
            Message.configError()
        return True
        
    def delete(self, identity, iterable):
        print>>sys.stderr, "delete"
        if self.email and self.path:
            lock = threading.Lock()
            lock.acquire()
            self.downloaderMap[identity].delete()
            self.downloaderMap.pop(identity)
            self.model.remove(iterable)
            if self.nowConnected == identity:
                self.singleSelected = False
                self.__disconnectButtons()
            for i in self.nowDeleting:
                if i == identity:
                    self.nowDeleting.remove(i)
            lock.release()
        print>>sys.stderr, "delete done"
        
    def __delete(self, widget, model, iterable):
        print>>sys.stderr, "__delete"
        if self.email and self.path:
            resp = Message.deleteFileYesNo()
            if resp != gtk.RESPONSE_DELETE_EVENT:
                identity, progress = model.get(iterable, 0, 5)
                _path = self.filenameEntry.get_text()
                self.nowDeleting.append(identity)
                print self.nowDeleting, self.nowConnected
                self.downloaderMap[identity].cancel()
                self.eventList.append({'id':identity, 'status':'delete', 'progress':float(progress.split('%')[0])})
                #self.delete(id, iter)
                print>>sys.stderr, 'appended'
                #try:
                #    os.unlink(path+'.lock')
                #except OSError:
                #    pass
                if resp == gtk.RESPONSE_YES:
                    try:
                        os.unlink(_path)
                    except OSError:
                        pass
                self.__disconnectButtons()
                print>>sys.stderr, '__delete done'
                #except OSError:
                #    pass
                #self.eventList.append({'id':id, 'status':'delete', 'progress':float(progress.split('%')[0])})
                #self.delete(id, iter)
        else:
            Message.configError()
        return True
        
    def __start(self, widget, model, iterable):
        if self.email and self.path:
            identity = model.get_value(iterable, 0)
            self.downloaderMap[identity].start()
            self.eventList.append({'id':identity, 'status':'queue', 'progress':0.0})
            model.set_value(iterable, 4, 'download')
        else:
            Message.configError()
        return True
                
    def __cancel(self, widget, model, iterable):
        if self.email and self.path:
            identity, status, progress = model.get(iterable, 0, 4, 5)
            if status != 'cancel':
                self.downloaderMap[identity].cancel()
                self.eventList.append({'id':identity, 'status':'cancel', 'progress':float(progress.split('%')[0])})
        else:
            Message.configError()
        return True
        
    def __open(self, widget, model, iterable):
        if self.email and self.path:
            identity, status = model.get(iterable, 0, 4)
            if status == 'done':
                try:
                    if platform.system() == 'Windows':
                        os.startfile(os.path.normpath(self.filenameEntry.get_text()))
                    elif platform.system() == 'Darwin':
                        os.system('open '+os.path.normpath(self.filenameEntry.get_text()))
                    else:
                        gtk.show_uri(screen=None, uri='file://'+os.path.normpath(self.filenameEntry.get_text()), timestamp=gtk.gdk.CURRENT_TIME)
                except gio.Error:
                    Message.gioError()
        else:
            Message.configError()
        return True
        
    def createList(self):
        self.model = gtk.ListStore(int, str, str, str, str, str)
        treeView = gtk.TreeView(self.model)
        treeView.set_reorderable(True)
        treeView.set_search_column(0)
        treeSelection = treeView.get_selection()
        treeSelection.set_mode(gtk.SELECTION_SINGLE)
        treeSelection.set_select_function(self.__listHandler, data=None, full=True)
        
        scrolledWindow = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)
        scrolledWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolledWindow.add_with_viewport(treeView)
        
        j = 0
        for i in [_('Id'), _('Url'), _('Total Size'), _('Dowloaded Size'), _('Status'), _('Percentage')]:
            cell = gtk.CellRendererText()
            column = gtk.TreeViewColumn(i, cell, text=j)
            column.set_resizable(True)
            if i == _('Url'):
                column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
                column.set_fixed_width(160)
            column.set_reorderable(True)
            column.set_clickable(True)
            treeView.append_column(column)
            j += 1
            
        scrolledWindow.show_all()
        return scrolledWindow
        
    def createText(self):
        VBox = gtk.VBox(homogeneous=False, spacing=0)
        HBox = gtk.HBox(homogeneous=False, spacing=0)
        
        openimg = gtk.Image()
        openimg.set_from_icon_name('terminal', 1)
        self.openButton.set_image(openimg)
        self.openButton.set_tooltip_text(_('open/execute'))
        self.openButton.set_alignment(0.5, 0.5)
        HBox.pack_end(self.openButton, expand=False, fill=False, padding=0)
        VBox.pack_end(HBox, expand=False, fill=False, padding=0)
        
        cancelimg = gtk.Image()
        cancelimg.set_from_icon_name('media-playback-stop', 1)
        self.cancelButton.set_image(cancelimg)
        self.cancelButton.set_tooltip_text(_('cancel download'))
        self.cancelButton.set_alignment(0.5, 0.5)
        HBox.pack_end(self.cancelButton, expand=False, fill=False, padding=0)
        
        startimg = gtk.Image()
        startimg.set_from_icon_name('media-playback-start', 1)
        self.startButton.set_image(startimg)
        self.startButton.set_tooltip_text(_('restart download'))
        self.startButton.set_alignment(0.5, 0.5)
        HBox.pack_end(self.startButton, expand=False, fill=False, padding=0)
        
        delimg = gtk.Image()
        delimg.set_from_icon_name('remove', 1)
        self.delButton.set_image(delimg)
        self.delButton.set_tooltip_text(_('delete download'))
        self.delButton.set_alignment(0.5, 0.5)
        HBox.pack_end(self.delButton, expand=False, fill=False, padding=0)
        
        addimg = gtk.Image()
        addimg.set_from_icon_name('add', 1)
        self.addButton.set_image(addimg)
        self.addButton.set_tooltip_text(_('add new download'))
        self.addButton.connect("clicked", self.__add)
        self.addButton.set_alignment(0.5, 0.5)
        HBox.pack_end(self.addButton, expand=False, fill=False, padding=0)
        HBox.pack_start(self.filenameEntry, expand=True, fill=True, padding=0)
        
        return VBox

